package models.state;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class EnvStateGraph {

	/**
	 * List of Big State
	 */
	private List<State> states;
	
	/**
	 * List of Transitions betweeen states
	 */
	private List<Transition> transitions;

	/**
	 * @return the states
	 */
	public List<State> getStates() {
		return states;
	}

	/**
	 * @param states the states to set
	 */
	public void setStates(List<State> states) {
		this.states = states;
	}

	/**
	 * @return the transitions
	 */
	public List<Transition> getTransitions() {
		return transitions;
	}

	/**
	 * @param transitions the transitions to set
	 */
	public void setTransitions(List<Transition> transitions) {
		this.transitions = transitions;
	}
	
	
	/**
	 * Find reachable state. Currently can only go one step. May need to implement as recursive.
	 *
	 * @param actions the actions
	 * @param currStates the curr states
	 * @return the list
	 */
	public void findReachableStateAndUpdate(List<String> actions, Set<State> currStates) {
	    Set<State> states = new HashSet<State>();
	    for(Transition tran : this.getTransitions()) {
	        for(State currState : currStates) {
    	        if(tran.getFrom().equals(currState.getId())) {
    	            boolean found = false;
                    for(String act : tran.getActions()) {
                        //if agent cannot perform this action, select state
                        for(String agtAct : actions) {
                            if(act.equals(agtAct)) {
                                found = true;
                                break;
                            }
                        }
                        if(found) {
                            break;
                        }
                    }
    	            //if act not found, transition can be trigger by others, possible state
    	            if(!found) {
        	            State destState = findStateById(tran.getTo());
        	            if(destState != null) {
        	                states.add(destState);
        	            }
    	            }
    	        }
	        }
	    }
	    currStates.addAll(states);
	}
	
	
	public State findStateById(String stateId) {
	    for(State state : states) {
	        if(state.getId().equals(stateId)) {
	            return state;
	        }
	    }
	    return null;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((states == null) ? 0 : states.hashCode());
		result = prime * result
				+ ((transitions == null) ? 0 : transitions.hashCode());
		return result;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		EnvStateGraph other = (EnvStateGraph) obj;
		if (states == null) {
			if (other.states != null)
				return false;
		} else if (!states.equals(other.states))
			return false;
		if (transitions == null) {
			if (other.transitions != null)
				return false;
		} else if (!transitions.equals(other.transitions))
			return false;
		return true;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "EnvStateGraph [states=" + states + ", transitions="
				+ transitions + "]";
	}
	
	
	
	
	
}
